var ServerState = {
  WAITING_FOR_START:  0,
  INIT1:              1,
  INIT2:              2,
  PLAYING_GAME:       3,
  GAME_ENDED:         4
};

var CatanClient = function (name, display) {
  // typedef GameInfo {{ id:int, num_players:int }}
  var log = function(s) {
    window.log('[ client ' + this.name + ' ] ' + s);
  };
  this.name = name;
  this.log  = log;
  var client_api = [
    'registration_accepted',  // gamelist: Array<GameInfo>
    'update_gamelist',        // gamelist: Array<GameInfo>
    'init_board',
    'update_context',
    'resource_acquired',
    'devcard_acquired',
    'timeout_turn',
    'message_received',
    'end_game',
    'error'
  ];
  
  this.display    = display;
  this.gamelist   = null;
  this.player_idx = -1;
  this.turn       = 0;
  this.game       = null;
  this.playerlist = null;
  this.context    = null;
  this.token      = null;
  this.started    = false;
  this.init_state = {
    road1: false,
    road2:false,
    sett1: false,
    sett2: false
  };
};

CatanClient.prototype.registration_accepted = function(data) {
  log('hurrah, your registration has been accepted. your token is: ' + data.token);
  log('available games: ' + JSON.stringify(data.gamelist))
  
  this.update_gamelist(data);
  var self = this;
  
  var interval = setInterval(function() {
    if (window.GameID != null) {
      self.display.join_game(window.GameID);
      clearInterval(interval);
    }
  }, 300);
};

CatanClient.prototype.update_gamelist = function(data) {
  this.gamelist = data.gamelist;
  this.display.render_gamelist(this.gamelist);
};

CatanClient.prototype.message_received = function(data) {
  log("f:" + data.token + "=>" + data.msg)
  appendMessage("f:" + data.token + "=>" + data.msg)
};

CatanClient.prototype.init_board = function(data) {
	  Display.static_data = data;
};

CatanClient.prototype.update_context = function(data) {
  this.context = data;
  displayPlayerList(this.context.players);
  if (this.player_idx < 0) {
    for (var i = 0; i < this.context.players.length; i++) {
      if (this.context.players[i].token == this.token) {
        this.player_idx = i;
        break;
      }
    }
  }
  
  if (this.context.cur_player == this.player_idx) {
    switch (this.context.game_state) {
      case ServerState.INIT1:
        this.display.selected_edge_id   = this.game.init1[this.player_idx].road;
        this.display.selected_vertex_id = this.game.init1[this.player_idx].sett;
        
        if (!this.init_state.sett1) {
          this.display.init_settlement();
          this.init_state.sett1 = true;
        }
        if (!this.init_state.road1) {
          this.display.init_road();
          this.init_state.road1 = true;
        }
        
        if (this.init_state.sett1 && this.init_state.road1) {
          this.display.end_turn();
        }
        break;
      case ServerState.INIT2:
        this.display.selected_edge_id   = this.game.init2[this.player_idx].road;
        this.display.selected_vertex_id = this.game.init2[this.player_idx].sett;
        if (!this.init_state.sett2) {
          this.display.init_settlement();
          this.init_state.sett2 = true;
        }
        if (!this.init_state.road2) {
          this.display.init_road();
          this.init_state.road2 = true;
        }
        if (this.init_state.sett2 && this.init_state.road2) {
          this.display.end_turn();
        }
        break;
      case ServerState.PLAYING_GAME:
        //for (var i = 0; i < this.game)
        break;
    }
  }
  
  this.display.render(this.context);
};


CatanClient.prototype.resource_acquired = function(data) {
  log('you received resources! ' + JSON.stringify(data.resources));
};

CatanClient.prototype.devcard_acquired = function(data) {
  log('you received a devcard! ' + JSON.stringify(data.devcards));
};

CatanClient.prototype.timeout_turn = function() {
  log('sorry! you took too long!');
};
  
CatanClient.prototype.end_game = function(data) {
  log(data.winner + ' has won!');
};

CatanClient.prototype.error = function(data) {
    log('the server responded with an error:\n  ' + data.message);
};

var CatanClientHost = function() { };

CatanClientHost.prototype = new CatanClient();

CatanClientHost.prototype.registration_accepted = function(data) {
  this.log('Hurray, your registration has been accepted.' 
              + ' Your token is: ' + data.token);
  this.log('You are The Host.');
  this.display.host_game();
};

CatanClientHost.prototype.update_context = function(data) {
  CatanClient.prototype.update_context.call(this, data);
  window.GameID = this.context.id;
};

CatanClientHost.prototype.update_gamelist = function(data) {
  CatanClient.prototype.update_gamelist.call(this, data);
  for (var i = 0; i < this.gamelist.length; i++) {
    if (this.gamelist[i].id == window.GameID) {
      if (this.gamelist[i].num_players > 1 && !this.started) {
        this.display.start_game();
      }
      break;
    }
  }
};

var CatanClientPlayer = function() { };

CatanClientPlayer.prototype = new CatanClient();

CatanClientPlayer.prototype.update_context = function(data) {
  CatanClient.prototype.update_context.call(this, data);
};
